package com.haircut.project.service.config.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haircut.project.dao.config.ProjectConfigMapper;
import com.haircut.project.model.config.ProjectConfig;
import com.haircut.project.service.category.ICategoryService;
import com.haircut.project.service.config.IConfigService;
import com.haircut.project.vo.catetory.CategoryVo;
import com.haircut.project.vo.config.ConfigReqVo;
import com.haircut.project.vo.config.ConfigResVo;
import com.haircut.project.vo.config.ConfigSttVo;
import com.haircut.project.vo.config.ConfigVo;
import com.haircut.sys.utils.PageUtils;
import com.haircut.sys.utils.user.SecurityUtils;
import com.modular.constant.BaseCodeDesc;
import com.modular.constant.NumberConstant;
import com.modular.enums.DataStts;
import com.modular.exception.ModularException;
import com.modular.result.PageResult;
import com.modular.utils.DBUtils;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ConfigServiceImpl implements IConfigService {
    @Autowired
    private ProjectConfigMapper projectConfigMapper;
    @Autowired
    @Qualifier("modularSnowflake")
    private Snowflake snowflake;
    @Autowired
    private ICategoryService categoryService;

    /**
     * 分页查询数据
     * @param reqVo
     * @return
     */
    @Override
    public PageResult<ConfigResVo> findPage(ConfigReqVo reqVo)
    {
        reqVo.setProjectName(DBUtils.escapeQuryLikeParam(reqVo.getProjectName()));
        IPage<?> pageReq = Page.of(reqVo.getPageNum(),reqVo.getPageSize());
        Page<ConfigResVo> page = projectConfigMapper.findPage(pageReq,reqVo);
        if(ObjectUtil.isNull(page) || CollUtil.isEmpty(page.getRecords())){
            return PageUtils.cover(reqVo);
        }
        List<String> categoryIdList = page.getRecords().stream().map(ConfigResVo::getCategoryId).distinct().toList();
        Map<String, CategoryVo> categoryVoMap = categoryService.findByIdList(categoryIdList);
        CategoryVo categoryVo = null;
        for(ConfigResVo resVo:page.getRecords()){
            categoryVo = categoryVoMap.get(resVo.getCategoryId());
            resVo.setCategoryName(categoryVo.getCategoryName());
            resVo.setParentId(categoryVo.getParentId());
        }
        return PageUtils.cover(page);
    }

    /**
     * 保存配置
     * @param configVo
     */
    @Override
    public void save(ConfigVo configVo)
    {
        // 判断项目名称是否重复
        checkProjectName(configVo.getProjectName(),null);
        Date currDate = DateUtil.date();
        String userId = SecurityUtils.getUserId();
        ProjectConfig config = new ProjectConfig();
        BeanUtils.copyProperties(configVo,config);
        config.setId(snowflake.nextIdStr());
        config.setDataStts(DataStts.ENABLED.getCode());
        config.setShareType(NumberConstant.ONE);
        config.setOrderNum(Optional.ofNullable(configVo.getOrderNum()).orElse(NumberConstant.ZERO));
        config.setCreateDate(currDate);
        config.setModifyDate(currDate);
        config.setCreateUserId(userId);
        config.setModifyUserId(userId);
        projectConfigMapper.insert(config);

    }

    /**
     * 修改配置
     * @param configVo
     */
    @Override
    public void mdoify(ConfigVo configVo)
    {
        if(StrUtil.isBlank(configVo.getId())){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"项目id必须填写");
        }
        ProjectConfig config = projectConfigMapper.selectById(configVo.getId());
        if(ObjectUtil.isNull(config)){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"项目id必须填写");
        }
        // 判断项目名称是否重复
        checkProjectName(configVo.getProjectName(),configVo.getId());
        Date currDate = DateUtil.date();
        String userId = SecurityUtils.getUserId();
        LambdaUpdateWrapper<ProjectConfig> modify = Wrappers.lambdaUpdate();
        modify.set(ProjectConfig::getModifyDate,currDate).set(ProjectConfig::getModifyUserId,userId);
        modify.set(ProjectConfig::getProjectAmount,configVo.getProjectAmount()).set(ProjectConfig::getProjectName,configVo.getProjectName());
        modify.set(ProjectConfig::getShareType, Optional.ofNullable(configVo.getShareType()).orElse(NumberConstant.ONE));
        modify.set(ProjectConfig::getTechnicianRate,configVo.getTechnicianRate());
        modify.set(ProjectConfig::getOrderNum,Optional.ofNullable(configVo.getOrderNum()).orElse(NumberConstant.ZERO));
        modify.set(ProjectConfig::getCategoryId,configVo.getCategoryId());
        modify.eq(ProjectConfig::getId,configVo.getId());
        projectConfigMapper.update(modify);

    }

    /**
     * 删除分类
     * @param configId
     */
    @Override
    public void delConfig(String configId)
    {
        if(StrUtil.isBlank(configId)){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"项目id必须填写");
        }
        ProjectConfig config = projectConfigMapper.selectById(configId);
        if(ObjectUtil.isNull(config)){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"项目id必须填写");
        }
        Date currDate = DateUtil.date();
        String userId = SecurityUtils.getUserId();
        LambdaUpdateWrapper<ProjectConfig> modify = Wrappers.lambdaUpdate();
        modify.set(ProjectConfig::getModifyDate,currDate).set(ProjectConfig::getModifyUserId,userId);
        modify.set(ProjectConfig::getDataStts,DataStts.DELETE.getCode());
        modify.eq(ProjectConfig::getId,config.getId());
        projectConfigMapper.update(modify);
    }

    /**
     * 修改状态
     */
    @Override
    public void modifyStts(ConfigSttVo sttVo)
    {
        Date currDate = DateUtil.date();
        String userId = SecurityUtils.getUserId();
        LambdaUpdateWrapper<ProjectConfig> modify = Wrappers.lambdaUpdate();
        modify.set(ProjectConfig::getModifyDate,currDate).set(ProjectConfig::getModifyUserId,userId);
        modify.set(ProjectConfig::getDataStts,sttVo.getDataStts());
        modify.eq(ProjectConfig::getId,sttVo.getId());
        projectConfigMapper.update(modify);
    }

    /**
     * 判断名称是否重复
     * @param projectName
     * @param id
     */
    private void checkProjectName(String projectName,String id){
        LambdaQueryWrapper<ProjectConfig> query = Wrappers.lambdaQuery();
        query.eq(ProjectConfig::getProjectName,projectName);
        if(StrUtil.isNotBlank(id)){
            query.ne(ProjectConfig::getId,id);
        }
        Long count = projectConfigMapper.selectCount(query);
        if(ObjectUtil.isNotNull(count) && count > NumberConstant.ZERO){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"项目名称重复");
        }
    }

    /**
     * 根据分类查询项目信息
     * @param cateId
     * @return
     */
    @Override
    public List<ConfigVo> findByCateId(String cateId)
    {
        LambdaQueryWrapper<ProjectConfig> query = Wrappers.lambdaQuery();
        query.eq(ProjectConfig::getCategoryId,cateId);
        query.eq(ProjectConfig::getDataStts,DataStts.ENABLED.getCode());
        List<ProjectConfig> list = projectConfigMapper.selectList(query);
        if(CollUtil.isEmpty(list)){
            return Collections.emptyList();
        }
        List<ConfigVo> configVoList = new ArrayList<>(list.size());
        ConfigVo configVo = null;
        for(ProjectConfig config:list){
            configVo = new ConfigVo();
            configVo.setText(config.getProjectName());
            configVo.setValue(config.getId());
            BeanUtils.copyProperties(config,configVo);
            configVoList.add(configVo);
        }
        return configVoList;
    }
}
